#include <mcp/server/fastmcp.h>
#include <iostream>
#include <string>
#include <memory>

using namespace mcp;
using namespace mcp::server;
using namespace mcp::types;

// Echo tool - returns the input message
Result<json::Value> echo_tool(const json::Value& args, Context<>& context) {
    if (!args.contains("message")) {
        return Error::invalid_params("Missing required parameter: message");
    }

    std::string message = args["message"].as_string();

    // Log the echo operation
    context.info(std::format("Echoing message: {}", message));

    // Report progress
    context.report_progress(0.5, 1.0, "Processing echo...");

    return json::Value::object({
        {"echo", message},
        {"timestamp", std::to_string(std::chrono::system_clock::now().time_since_epoch().count())},
        {"server", "MCP Echo Server"}
    });
}

// Echo resource - returns a simple echo response
Result<ResourceContent> echo_resource(const std::string& uri, Context<>& context) {
    context.info(std::format("Echo resource requested: {}", uri));

    // Extract message from URI
    std::string message = "Hello from echo resource!";
    if (uri.find("echo://") == 0) {
        message = uri.substr(7); // Remove "echo://" prefix
    }

    return ResourceContent{
        .contents = std::vector<std::shared_ptr<ContentBlock>>{
            std::make_shared<TextContent>(std::format("Echo Resource: {}", message))
        },
        .uri = uri
    };
}

// Echo prompt - generates a conversation prompt
Result<std::vector<PromptMessage>> echo_prompt(const json::Value& args, Context<>& context) {
    std::string topic = "general conversation";
    if (args.contains("topic")) {
        topic = args["topic"].as_string();
    }

    context.info(std::format("Generating echo prompt for topic: {}", topic));

    return std::vector<PromptMessage>{
        PromptMessage{
            .role = PromptRole::System,
            .content = std::make_shared<TextContent>(
                std::format("You are a helpful assistant for {}. "
                           "Respond to the user's message clearly and concisely.", topic)
            )
        },
        PromptMessage{
            .role = PromptRole::User,
            .content = std::make_shared<TextContent>(
                "Hello! Please introduce yourself and tell me what you can help with."
            )
        }
    };
}

int main() {
    try {
        std::cout << "MCP C++ Echo Server Example\n";
        std::cout << "===========================\n\n";

        // Create server configuration
        ServerConfig config{
            .name = "MCP Echo Server",
            .version = "1.0.0",
            .description = "Simple echo server that demonstrates MCP basics",
            .debug = true,
            .host = "localhost",
            .port = 8081
        };

        // Create server
        auto server = std::make_shared<FastMCPServer>(config);

        // Register echo tool
        ToolOptions echo_tool_options{
            .description = "Echo back the input message",
            .input_schema = json::object_schema()
                .property("message", json::string_schema().description("Message to echo back"))
                .required({"message"})
        };

        server->tool("echo", echo_tool, echo_tool_options);

        // Register echo resource
        ResourceOptions echo_resource_options{
            .name = "Echo Resource",
            .description = "Returns an echo response based on the URI",
            .mime_type = "text/plain"
        };

        server->resource("echo://", echo_resource, echo_resource_options);

        // Register echo prompt
        PromptOptions echo_prompt_options{
            .description = "Generate a conversation prompt"
        };

        server->prompt("echo", echo_prompt, echo_prompt_options);

        // Add a lifespan handler
        server->lifespan<void>([](void& context) {
            std::cout << "Server is starting up...\n";
            // Startup initialization code here
        });

        // Display server info
        std::cout << "Server configuration:\n";
        std::cout << "  Name: " << config.name << "\n";
        std::cout << "  Version: " << config.version << "\n";
        std::cout << "  Host: " << config.host << ":" << config.port << "\n\n";

        // Display registered capabilities
        std::cout << "Registered capabilities:\n";
        std::cout << "  Tools (" << server->list_tools().size() << "):\n";
        for (const auto& tool : server->list_tools()) {
            std::cout << "    - " << tool.name << ": " << tool.description << "\n";
        }

        std::cout << "  Resources (" << server->list_resources().size() << "):\n";
        for (const auto& resource : server->list_resources()) {
            std::cout << "    - " << resource.uri << ": " << resource.name << "\n";
        }

        std::cout << "  Prompts (" << server->list_prompts().size() << "):\n";
        for (const auto& prompt : server->list_prompts()) {
            std::cout << "    - " << prompt.name << ": "
                     << (prompt.description ? *prompt.description : "No description") << "\n";
        }

        std::cout << "\nStarting server with stdio transport...\n";
        std::cout << "Example usage:\n";
        std::cout << "  - Call echo tool: {\"method\":\"tools/call\",\"params\":{\"name\":\"echo\",\"arguments\":{\"message\":\"Hello World\"}}}\n";
        std::cout << "  - Read resource: {\"method\":\"resources/read\",\"params\":{\"uri\":\"echo://test\"}}\n";
        std::cout << "  - Call prompt: {\"method\":\"prompts/call\",\"params\":{\"name\":\"echo\",\"arguments\":{\"topic\":\"technology\"}}}\n";
        std::cout << "\nPress Ctrl+C to stop the server\n";

        // Run server with stdio transport
        server->run<mcp::transport::StdioTransport>();

    } catch (const std::exception& e) {
        std::cerr << "Error: " << e.what() << "\n";
        return 1;
    }

    return 0;
}